package com.andaily.domain.dto.developer;

import com.andaily.domain.developer.Backlog;
import com.andaily.domain.developer.SprintPriority;
import com.andaily.domain.developer.SprintTask;
import com.andaily.domain.developer.SprintTaskStatus;
import com.andaily.domain.developer.operation.SprintTimeUtils;
import com.andaily.domain.dto.AbstractDTO;
import com.andaily.domain.shared.DateUtils;
import org.apache.commons.lang.StringEscapeUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Date: 13-8-7
 *
 * @author Shengzhao Li
 */
public class SprintTaskDto extends AbstractDTO {

    protected String number;
    protected String name;
    protected String estimateTime;
    protected String actualUsedTime;

    protected int estimateTimeAsInt;
    protected int actualUsedTimeAsInt;

    protected SprintTaskStatus status = SprintTaskStatus.CREATED;
    protected String pendingTime;
    protected String finishTime;
    protected String createTime;

    protected String cancelTime;
    protected SprintPriority priority = SprintPriority.DEFAULT;
    protected boolean urgent;

    protected String description;
    protected int timeDifference;

    protected boolean referBacklog;
    protected boolean moved;

    public SprintTaskDto() {
    }

    public SprintTaskDto(SprintTask task) {
        super(task.guid());
        this.createTime = DateUtils.toDateTime(task.createTime());
        this.name = task.name();
        this.estimateTime = task.estimateTimeAsHour();
        this.actualUsedTime = task.actualUsedTimeAsHour();
        this.timeDifference = task.timeDifference();

        this.estimateTimeAsInt = task.estimateTime();
        this.actualUsedTimeAsInt = task.actualUsedTime();

        this.status = task.status();
        this.urgent = task.urgent();
        this.priority = task.priority();
        this.number = task.number();

        this.description = task.description();
        Backlog backlog = task.backlog();
        this.referBacklog = (backlog != null);
        this.moved = task.moved();

        Date pTime = task.pendingTime();
        if (pTime != null) {
            this.pendingTime = DateUtils.toDateTime(pTime);
        }
        Date cTime = task.cancelTime();
        if (cTime != null) {
            this.cancelTime = DateUtils.toDateTime(cTime);
        }
        Date fTime = task.finishTime();
        if (fTime != null) {
            this.finishTime = DateUtils.toDateTime(fTime);
        }
    }

    public static List<SprintTaskDto> toDtos(List<SprintTask> tasks) {
        List<SprintTaskDto> taskDtos = new ArrayList<SprintTaskDto>(tasks.size());
        for (SprintTask task : tasks) {
            taskDtos.add(new SprintTaskDto(task));
        }
        return taskDtos;
    }

    public boolean isReferBacklog() {
        return referBacklog;
    }

    public boolean isMoved() {
        return moved;
    }

    public void setMoved(boolean moved) {
        this.moved = moved;
    }

    public void setReferBacklog(boolean referBacklog) {
        this.referBacklog = referBacklog;
    }

    //Html style tooltip
    public String getTooltip() {
        StringBuilder sb = new StringBuilder("Created time: <span class='text-info'>");
        sb.append(createTime).append("</span><br/>");
        sb.append("Estimate time: <span class='text-info'>").append(estimateTime).append("</span><br/>");
        sb.append("Priority: <span class='text-info'>").append(priority.getLabel()).append("</span><br/>");
        switch (status) {
            case PENDING:
                sb.append("Starting time: <span class='text-info'>").append(pendingTime).append("</span><br/>");
                break;
            case CANCELED:
                sb.append("Canceled time: <span class='text-info'>").append(cancelTime).append("</span><br/>");
                break;
            case FINISHED:
                sb.append("Finished time: <span class='text-info'>").append(finishTime).append("</span><br/>");
                sb.append("Actual used: <span class='text-info'>").append(actualUsedTime).append("</span>")
                        .append(getTimeDifferenceAsHtml()).append("<br/>");
                break;
        }
        if (urgent) {
            sb.append("<span class='red'>Urgent</span>").append("<br/>");
        }
        sb.append("<span class='text-info'>").append(description).append("</span><br/>");
        return StringEscapeUtils.escapeHtml(sb.toString());
    }

    //Only use if the task status is FINISHED
    public String getTimeDifferenceAsHtml() {
        if (!SprintTaskStatus.FINISHED.equals(this.status)) {
            return "";
        }
        StringBuilder text = new StringBuilder();
        if (timeDifference > 0) {
            text.append("(<span class='blue'>-").append(SprintTimeUtils.taskTimeAsString(timeDifference)).append("</span>)");
        } else if (timeDifference < 0) {
            text.append("(<span class='red'>+").append(SprintTimeUtils.taskTimeAsString(-timeDifference)).append("</span>)");
        }
        return text.toString();
    }

    public int getTimeDifference() {
        return timeDifference;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEstimateTime() {
        return estimateTime;
    }

    public void setEstimateTime(String estimateTime) {
        this.estimateTime = estimateTime;
    }

    public String getActualUsedTime() {
        return actualUsedTime;
    }

    public void setActualUsedTime(String actualUsedTime) {
        this.actualUsedTime = actualUsedTime;
    }

    public SprintTaskStatus getStatus() {
        return status;
    }

    public void setStatus(SprintTaskStatus status) {
        this.status = status;
    }

    public String getPendingTime() {
        return pendingTime;
    }

    public void setPendingTime(String pendingTime) {
        this.pendingTime = pendingTime;
    }

    public String getFinishTime() {
        return finishTime;
    }

    public void setFinishTime(String finishTime) {
        this.finishTime = finishTime;
    }

    public String getCancelTime() {
        return cancelTime;
    }

    public void setCancelTime(String cancelTime) {
        this.cancelTime = cancelTime;
    }

    public SprintPriority getPriority() {
        return priority;
    }

    public void setPriority(SprintPriority priority) {
        this.priority = priority;
    }

    public boolean isUrgent() {
        return urgent;
    }

    public void setUrgent(boolean urgent) {
        this.urgent = urgent;
    }

    public int getEstimateTimeAsInt() {
        return estimateTimeAsInt;
    }

    public void setEstimateTimeAsInt(int estimateTimeAsInt) {
        this.estimateTimeAsInt = estimateTimeAsInt;
    }

    public int getActualUsedTimeAsInt() {
        return actualUsedTimeAsInt;
    }

    public void setActualUsedTimeAsInt(int actualUsedTimeAsInt) {
        this.actualUsedTimeAsInt = actualUsedTimeAsInt;
    }
}
